<?php

abstract class Kd_Data_Dcl_Expression_Where_Base extends Kd_Data_Dcl_Expression_Base {

    private $_isNot = FALSE;

    public function __construct() {
        parent::__construct();
    }

    protected function addExpression(Kd_Data_Dcl_Expression_Base $expression) {
        if (!$this->getChildExpressions()->isEmpty()) {
            $lastItem = $this->getChildExpressions()->getLastItem();
            $flag = $lastItem->getLogicFlag();
            if (is_null($flag)) {
                $this->andNext();
            }
        }
        if($this->_isNot){
            if($expression instanceof Kd_Data_Dcl_Expression_Where_Condition_Not){
                $expression->setIsNot(TRUE);
            }
        }
        $this->_isNot = FALSE;
        return parent::addExpression($expression);
    }

    public function not() {
        $this->_isNot = TRUE;
        return $this;
    }

    public function orNext() {
        $this->getChildExpressions()->getLastItem()->setLogicFlag('or');
        return $this;
    }

    public function andNext() {
        $this->getChildExpressions()->getLastItem()->setLogicFlag('and');
        return $this;
    }

    public function inQuery($left) {
        $result = new Kd_Data_Dcl_Expression_Subquery(Kd_Data_Factory::getQueryDcl());
        $result->setOwner($this->getOwner())->setParentExpression($this);
        $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Contain($left, $result));
        return $result->getQuery();
    }

    public function isNull($field) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Nullable($field));
    }

    public function gt($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'gt'));
    }

    public function lt($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'lt'));
    }

    public function eq($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'eq'));
    }

    public function gteq($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'gteq'));
    }

    public function lteq($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'lteq'));
    }

    public function neq($left, $right) {
        return $this->addExpression(new Kd_Data_Dcl_Expression_Where_Condition_Compare($left, $right, 'neq'));
    }

    public function like($left, $right) {
        $condition = new Kd_Data_Dcl_Expression_Where_Condition_Like($left, $right);
        if ($this->_isNot) {
            $condition->setIsNot(TRUE);
        }
        return $this->addExpression($condition);
    }

    public function contain($left, $right) {
        $condition = new Kd_Data_Dcl_Expression_Where_Condition_Contain($left, $right);
        if ($this->_isNot) {
            $condition->setIsNot(TRUE);
        }
        return $this->addExpression($condition);
    }

}